package com.zmn.brs.admin.controller.whitelist;

import com.google.common.collect.Lists;
import com.zmn.brs.admin.controller.BrsBaseController;
import com.zmn.brs.common.dictionary.Dict;
import com.zmn.common.dictionary.DictModel;
import com.zmn.common.dto2.ResponseDTO;
import com.zmn.common.utils.date.DateUtil;
import com.zmn.brs.model.entity.blacklist.Blacklist;
import com.zmn.brs.model.entity.whitelist.Whitelist;
import com.zmn.brs.model.entity.whitelist.query.WhitelistQuery;
import com.zmn.brs.services.interfaces.blacklist.BlacklistService;
import com.zmn.brs.services.interfaces.whitelist.WhitelistService;
import org.apache.shiro.util.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.*;

/**
 * 描述: 白名单基础控制类
 *
 * @author wangjie
 * @since 2019-08-01
 **/
public class WhitelistBaseController extends BrsBaseController {

    protected final Logger logger = LoggerFactory.getLogger(this.getClass());

    WhitelistService whitelistService;

    private BlacklistService blacklistService;

    @Autowired
    public WhitelistBaseController(WhitelistService whitelistService, BlacklistService blacklistService) {
        this.whitelistService = whitelistService;
        this.blacklistService = blacklistService;
    }

    /**
     * 描述:白名单
     *
     * @author wangjie
     * @since 2019/8/2
     **/
    private static final String WHITELIST_TYPE_NAME = "白名单";

    /**
     * 描述: 白名单类型 1 IP白名单,2 用户id白名单,3 手机号白名单
     **/
    private static final Integer WHITELIST_TYPE_IP = 1;
    private static final Integer WHITELIST_TYPE_USER_ID = 2;
    private static final Integer WHITELIST_TYPE_MOBILE_NUM = 3;

    private static final String WHITELIST_TYPE_IP_NAME = "IP白名单";
    private static final String WHITELIST_TYPE_USER_ID_NAME = "用户ID白名单";
    private static final String WHITELIST_TYPE_MOBILE_NUM_NAME = "手机号白名单";

    /**
     * 描述: 表头展示，根据不同的白名单类型 显示不同的title
     **/
    private static final String WHITELIST_TYPE_IP_TITLE = "IP";
    private static final String WHITELIST_TYPE_USER_ID_TITLE = "用户ID";
    private static final String WHITELIST_TYPE_MOBILE_TITLE = "手机号";

    /**
     * 描述: 配置白名单类型字典，不公用放在当前页面公共模块中
     *
     * @return java.util.List<com.zmn.common.dictionary.DictModel>
     **/
    static List<DictModel> getWhitelistTypeList() {

        List<DictModel> items = Lists.newArrayListWithExpectedSize(WHITELIST_TYPE_MOBILE_NUM);
        items.add(new DictModel(WHITELIST_TYPE_IP, WHITELIST_TYPE_IP_NAME));
        items.add(new DictModel(WHITELIST_TYPE_USER_ID, WHITELIST_TYPE_USER_ID_NAME));
        items.add(new DictModel(WHITELIST_TYPE_MOBILE_NUM, WHITELIST_TYPE_MOBILE_NUM_NAME));
        return items;
    }

    /**
     * 描述: 根据白名单类型num 翻译白名单name
     *
     * @param typeNum
     *            白名单类型 num
     * @return java.lang.String
     **/
    static String getWhitelistTypeNameByTypeNum(Integer typeNum) {

        return Dict.dictModelToMap(getWhitelistTypeList()).get(typeNum);
    }

    /**
     * 描述:配置白名单Title类型字典，不公用放在当前页面公共模块中 用于根据不同的白名单类型 Title
     *
     * @return java.util.List<com.zmn.common.dictionary.DictModel>
     **/
    private static List<DictModel> getWhitelistTypeTitleList() {

        List<DictModel> items = Lists.newArrayListWithExpectedSize(WHITELIST_TYPE_MOBILE_NUM);
        items.add(new DictModel(WHITELIST_TYPE_IP, WHITELIST_TYPE_IP_TITLE));
        items.add(new DictModel(WHITELIST_TYPE_USER_ID, WHITELIST_TYPE_USER_ID_TITLE));
        items.add(new DictModel(WHITELIST_TYPE_MOBILE_NUM, WHITELIST_TYPE_MOBILE_TITLE));
        return items;
    }

    /**
     * 描述: 根据白名单类型num 翻译白名单Title
     *
     * @param typeNum
     *            白名单类型 num
     * @return java.lang.String
     **/
    static String getWhitelistTypeTitleByTypeNum(Integer typeNum) {

        return Dict.dictModelToMap(getWhitelistTypeTitleList()).get(typeNum);
    }

    /**
     * 描述: 根据白名单数据和类型检查白名单重复问题，返回提示语 新增保存时，要判断系统是否已存在此IP黑白名单， 已存在则提示“系统已存在此IP黑名单”，“系统已存在此IP白名单”（白名单和黑名单互斥）
     *
     * @param whiteNum
     *            黑名单数据
     * @param whiteType
     *            黑名单类型
     * @return com.zmn.common.dto.ResultDTO
     * @author wangjie
     * @since 2019/8/2
     **/
    ResponseDTO checkBlacklistAndWhitelistByBlackNumAndBlackType(String whiteNum, Integer whiteType) {

        Whitelist whitelist = whitelistService.findByWhiteNumAndType(whiteNum, whiteType);

        if (Objects.isNull(whitelist.getWhitelistId())) {
            // 如果白名单为null 则查看黑名单是否为null （白名单和黑名单互斥）
            Blacklist blacklist = blacklistService.findByBlackNumAndType(whiteNum, whiteType);
            if (Objects.isNull(blacklist.getBlacklistId())) {
                return ResponseDTO.success(true,"当前数据可以写入数据库");
            } else {
                // 如果黑名单存在该数据
                String blacklistTitle = getWhitelistTypeTitleByTypeNum(whiteType);
                return ResponseDTO.fail("系统已存在此" + blacklistTitle + "黑名单");
            }
        } else {
            // 如果不为黑名单为null
            String whitelistTitle = getWhitelistTypeTitleByTypeNum(whiteType);
            return ResponseDTO.fail("系统已存在此" + whitelistTitle + "白名单");
        }
    }

    /**
     * 描述: 根据查询条件构建二维集合,导出数据准备
     *
     * @param query
     *            查询条件
     * @return java.util.ArrayList<java.util.List>
     * @author wangjie
     * @since 2019/8/2
     **/
    public ArrayList<List> outputExcel(WhitelistQuery query) {

        List<Whitelist> whitelists = Optional.ofNullable(whitelistService.listPageByQuery(query)).orElse(Collections.emptyList());

        ArrayList<List> arrayList = Lists.newArrayListWithExpectedSize(whitelists.size());
        ArrayList<String> headerList = this.buildHeader(query.getWhitelistType());
        arrayList.add(headerList);

        if (!CollectionUtils.isEmpty(whitelists)) {
            whitelists.forEach(e -> {
                List<Object> item = new ArrayList<>();
                item.add(e.getWhitelistNum());
                item.add(WHITELIST_TYPE_NAME);
                item.add(e.getCreater());
                item.add(DateUtil.subDate(e.getCreateTime()));
                arrayList.add(item);
            });
        }
        return arrayList;
    }

    /**
     * 描述: 构建表头
     *
     * @param blackType
     *            黑名单类型
     * @return java.util.ArrayList<java.lang.String>
     * @author wangjie
     * @since 2019/8/2
     **/
    private ArrayList<String> buildHeader(Integer blackType) {

        String titleByTypeNum = getWhitelistTypeTitleByTypeNum(blackType);
        String type = titleByTypeNum + "类型";
        String creater = "创建者";
        String createTime = "创建时间";
        ArrayList<String> titleHeader = Lists.newArrayList();
        titleHeader.add(titleByTypeNum);
        titleHeader.add(type);
        titleHeader.add(creater);
        titleHeader.add(createTime);
        return titleHeader;
    }
}
